#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:John Zhou
# Time:2022年05月20日
from PCANBasic import *        ## PCAN-Basic library import
# from PyQt5 import uic,QtCore,QtWidgets
import sys
import PyQt5.QtWidgets as qw
from PyQt5.QtWidgets import QApplication,QPushButton, QWidget, QTableWidgetItem,QTreeWidgetItem, QTreeWidget, QMainWindow
import threading
from time import sleep
from PyQt5.QtCore import QThread, pyqtSignal, QTimer, QObject
from PCANToolUI import *
import win32event
import math
from udsoncan.client import Client
from udsoncan.exceptions import TimeoutException
import udsoncan
from udsoncan.connections import BaseConnection,PythonIsoTpConnection
from udsoncan import services, Response, MemoryLocation
import isotp
from isotp import CanMessage
import queue
import time
from can.interfaces.pcan.pcan import PcanBus
from udsoncan.services import *
import udsoncan.configs
import os
import binascii
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Hash import CMAC
import hashlib
from binascii import b2a_hex, a2b_hex, unhexlify

TOPBIT = 0x8000
POLYNOM_1 = 0x8408
POLYNOM_2 = 0x8025
BITMASK = 0x0080
# INITIAL_REMINDER = 0xFFFE
MSG_LEN = 2 #seed length in bytes

L61_TOPBIT = 0x8000
L61_POLYNOM_1 = 0x2346
L61_POLYNOM_2 = 0x8752
L61_BITMASK = 0x0080
# L61_INITIAL_REMINDER = 0xFFFE
L61_MSG_LEN = 2

EGSM_TX_ID = 0x79D
EGSM_RX_ID_PHYS = 0x71D
EGSM_RX_ID_FUNC = 0x7DF
FLASH_DRIVER_ADDRESS = 0X1FFFE800
APP_ADDRESS = 0X8000
ecuXorArray = [0x47, 0x53, 0x4D, 0x4B]
ecuXorArray60 = [0x4B,0x4D,0x53,0x47]
class PrpCrypt(object):
    def __init__(self, key):
        # 初始化方法
        if isinstance(key, str):
            self.key = key.encode('utf-8')
        elif isinstance(key, bytes):
            self.key = key

        #self.iv = Random.new().read(AES.block_size)  #CBC模式使用，随机
        self.iv = '1234567812345678'.encode('utf-8')

    def encrypt(self, text):
        # 加密函数，如果text不足16个字节就使用空格来补足16位
        # 16位密钥规则
        # text-需要加密的数据
        # return 统一加密后的字符串转换为16进制字符串

        bs = AES.block_size  ##密钥的长度AES-128(16位)

        # PKCS5填充,填充缺少的位数值，例如加密的数据是4字节，那填充的就是(16-4)=12
        PADDING = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
        mode = AES.MODE_ECB               #使用ECB加密
        cryptor = AES.new(self.key, mode)

        if isinstance(text, str):  # 如果输入的是字符串
            self.ciphertext = cryptor.encrypt(PADDING(text).encode('utf-8'))

        elif isinstance(text, bytes):  # 如果输入的是二进制数
            count = len(text)  # 用户输入的字符串的长度
            if count < bs:
                add = (bs - count)
                for i in range(add):
                    text = text + chr(add).encode('utf-8') #逐一加上缺少的数值的bytes值
            elif count > bs:
                add = bs - (count % bs)
                for i in range(add):
                    text = text + chr(add).encode('utf-8')
            print("text：", text)
            self.ciphertext = cryptor.encrypt(text)
        else:
            print("Input data is not hashable.")

        print("密钥：", self.ciphertext)
        return self.ciphertext  #b2a_hex(self.ciphertext) #返回16进制数据

    def decrypt(self, code):
        # 解密函数
        mode = AES.MODE_ECB  # 使用ECB加密
        cryptor = AES.new(self.key, mode)
        plain_text = cryptor.decrypt(bytes.fromhex(code))
        for i in range(16):
            pad = chr(i).encode('utf-8')
            if pad in plain_text:
                text = plain_text.rstrip(chr(i).encode('utf-8'))
        return b2a_hex(text)

    def encrypt_CMA(self, secret, message):
        c = CMAC.new(secret, message, ciphermod=AES) #secret-16位密钥
        code = c.hexdigest()
        print("CMAC code:", code)
        return (code)
###*****************************************************************
### Timer class
###*****************************************************************

class TimerRepeater(object):
    """
    A simple timer implementation that repeats itself
    """

    # Constructor
    #
    def __init__(self, name, interval, target, isUi, args=[], kwargs={}):
        """
        Creates a timer.

        Parameters:
            name        name of the thread
            interval    interval in second between execution of target
            target      function that is called every 'interval' seconds
            args        non keyword-argument list for target function
            kwargs      keyword-argument list for target function
        """
        # define thread and stopping thread event
        self._name = name
        self._thread = None
        self._event = None
        self._isUi = isUi
        # initialize target and its arguments
        self._target = target
        self._args = args
        self._kwargs = kwargs
        # initialize timer
        self._interval = interval
        self._bStarted = False

    # Runs the thread that emulates the timer
    #
    def _run(self):
        """
        Runs the thread that emulates the timer.

        Returns:
            None
        """
        while not self._event.wait(self._interval):
            if self._isUi:
                # launch target in the context of the main loop
                pass
                # root.after(1, self._target,*self._args, **self._kwargs)
            else:
                self._target(*self._args, **self._kwargs)

    # Starts the timer
    #
    def start(self):
        """
        Starts the timer

        Returns:
            None
        """
        # avoid multiple start calls
        if (self._thread == None):
            self._event = threading.Event()
            self._thread = threading.Thread(None, self._run, self._name)
            self._thread.start()

    # Stops the timer
    #
    def stop(self):
        """
        Stops the timer

        Returns:
            None
        """
        if (self._thread != None):
            self._event.set()
            self._thread = None

# 自定义信号
class ShiftSignal(QObject):
    park = pyqtSignal(int)
    reverse = pyqtSignal(int)
    neutral = pyqtSignal(int)
    high = pyqtSignal(int)
    low = pyqtSignal(int)
# # 实例化自定义信号
UI_SIGNAL = ShiftSignal()

class myMainWindow(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.DeviceInit()
        self.REFRESH_VALUE = 0
        # self.myTimer()

        # 绑定信号与槽
        self.actionChannel01.triggered.connect(self.actionChannel01_cb)         # 连接通道1
        self.btn_ReadMsg.clicked.connect(self.btn_ReadMsg_cb)                   # 挡位显示开始
        self.btn_HW.clicked.connect(self.ReadHWVersion)                         # 读硬件版本
        self.btn_SW.clicked.connect(self.ReadSWVersion)                         # 读软件版本
        self.btn_BOOT.clicked.connect(self.ReadBOOTVersion)                     # 读取Boot版本
        self.btn_SpareNumber.clicked.connect(self.ReadSparePartNum)             # 读取Spare Part Number
        self.btn_SerialNumber.clicked.connect(self.ReadSerialNum)               # 读取Serial Number
        self.btn_SupplierCode.clicked.connect(self.ReadSupplierNum)             # 读取供应商代码
        self.btn_FingerPrint.clicked.connect(self.ReadFingerPrint)              # 读取软件指纹信息
        self.btn_VIN.clicked.connect(self.ReadVINCode)                          # 读VIN
        self.btn_ActiveSession.clicked.connect(self.ReadActiveSession)          # 读当前有效会话
        self.btn_ReadNetConfig.clicked.connect(self.ReadNetConfig)              # 读网络配置
        self.btn_ProgrammingCount.clicked.connect(self.ReadProgrammingCount)    # 读成功编程次数
        self.btn_power.clicked.connect(self.ReadPower)                          # 读电源电压
        self.btn_VehicleSpeed.clicked.connect(self.ReadVehicleSpeed)            # 读车速
        self.btn_EngineSpeed.clicked.connect(self.ReadEngineSpeed)              # 读发动机转速
        self.btn_Odometer.clicked.connect(self.ReadOdoMeter)                    # 读里程
        self.btn_MotoSpeed.clicked.connect(self.ReadMotoSpeed)                  # 读电机转速
        self.btn_TotalPower.clicked.connect(self.ReadTotalPower)                # 读动力电池电压
        self.btn_SOC.clicked.connect(self.ReadSOC)                              # 读电池剩余电量百分比
        self.btn_ButtonState.clicked.connect(self.ReadButtonState)              # 读按钮状态
        self.btn_LedState.clicked.connect(self.ReadLedState)                    # 读LED状态

        self.btn_writeEcuNo.clicked.connect(self.WriteEcuNo)                    # 写序列号
        self.btn_writeSparePartNum.clicked.connect(self.WriteSparePartNum)      # 写spare part number
        self.btn_writeVIN.clicked.connect(self.WriteVINCode)                    # 写VIN
        self.btn_writeNetConfigure.clicked.connect(self.WriteNetConfigure)      # 写网络配置信息

        self.btn_CurrentDTC.clicked.connect(self.ReadCurrentDTC)                # 读取当前故障代码
        self.btn_HistoryDTC.clicked.connect(self.ReadHistoryDTC)                # 读取历史故障代码
        self.btn_ClearDTC.clicked.connect(self.btn_eraseDTC_cb)                 # 清除故障代码
        self.btn_ReadSnapShot.clicked.connect(self.ReadSnapShot)                # 读故障快照
        self.btn_ReadExtendData.clicked.connect(self.ReadExtendData)            # 读故障快照
        self.btn_clearMsg.clicked.connect(self.btn_clearDTC_cb)                 # 清除显示文本

        self.IO_P.toggled.connect(self.IO_P_cb)
        self.IO_R.toggled.connect(self.IO_R_cb)
        self.IO_N.toggled.connect(self.IO_N_cb)
        self.IO_L.toggled.connect(self.IO_L_cb)
        self.IO_H.toggled.connect(self.IO_H_cb)
        self.IO_BK.toggled.connect(self.IO_BK_cb)
        self.IO_OFF.toggled.connect(self.IO_OFF_cb)
        self.IO_ON.toggled.connect(self.IO_ON_cb)
        # 绑定信号与槽
        UI_SIGNAL.park.connect(self.refreshPark)
        UI_SIGNAL.reverse.connect(self.refreshReverse)
        UI_SIGNAL.neutral.connect(self.refreshNeutral)
        UI_SIGNAL.low.connect(self.refreshLow)
        UI_SIGNAL.high.connect(self.refreshHigh)

    # 界面及参数初始化
    def DeviceInit(self):
        self.m_objPCANBasic = PCANBasic()
        self.m_PcanHandle = PCAN_USBBUS1
        self.m_CanRead = False
        self.m_ReadThread = None
        self.m_Terminated = False
        self._lock = threading.RLock()
        self.m_ReceiveEvent = win32event.CreateEvent(None, 0, 0, None)
        # bManualReset(参数2)：[输入]指定将事件对象创建成手动复原还是自动复原。如果是TRUE，那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。
        # 如果设置为FALSE，当事件被一个等待线程释放以后，系统将会自动将事件状态复原为无信号状态。
        # bInitialState（参数3）：[输入]指定事件对象的初始状态。如果为TRUE，初始状态为有信号状态；否则为无信号状态。
        self.tmrRead = TimerRepeater("tmrRead", 0.050, self.tmrRead_Tick, False)
        self.isCh1Open = False
        self.isCh1HasMes = False
        self.is_extendMode = False
        self.is_L61 = False

        # RadioButton设为不能点击
        self.rbt_park.setEnabled(False)
        self.rbt_reverse.setEnabled(False)
        self.rbt_neutral.setEnabled(False)
        self.rbt_low.setEnabled(False)
        self.rbt_high.setEnabled(False)

        self.IO_BK.setEnabled(False)
        self.IO_P.setEnabled(False)
        self.IO_R.setEnabled(False)
        self.IO_N.setEnabled(False)
        self.IO_L.setEnabled(False)
        self.IO_H.setEnabled(False)
        self.IO_ON.setEnabled(False)
        self.IO_OFF.setEnabled(False)

        # emit信号初始化
        self.position_park = 0
        self.position_reverse= 0
        self.position_center= 0
        self.position_high= 0
        self.position_low= 0
        # RadioButton颜色设置
        self.rbt_park.setStyleSheet("QRadioButton::indicator {width:15px;height:15px;border-radius:7px}"
                                        "QRadioButton::indicator:checked {background-color:rgb(85, 170, 255);}"
                                        "QRadioButton::indicator:unchecked {background-color:rgb(255, 255, 255);}")
        self.rbt_reverse.setStyleSheet("QRadioButton::indicator {width:15px;height:15px;border-radius:7px}"
                                        "QRadioButton::indicator:checked {background-color:rgb(85, 170, 255);}"
                                        "QRadioButton::indicator:unchecked {background-color:rgb(255, 255, 255);}")
        self.rbt_neutral.setStyleSheet("QRadioButton::indicator {width:15px;height:15px;border-radius:7px}"
                                        "QRadioButton::indicator:checked {background-color:rgb(85, 170, 255);}"
                                        "QRadioButton::indicator:unchecked {background-color:rgb(255, 255, 255);}")
        self.rbt_low.setStyleSheet("QRadioButton::indicator {width:15px;height:15px;border-radius:7px}"
                                        "QRadioButton::indicator:checked {background-color:rgb(85, 170, 255);}"
                                        "QRadioButton::indicator:unchecked {background-color:rgb(255, 255, 255);}")
        self.rbt_high.setStyleSheet("QRadioButton::indicator {width:15px;height:15px;border-radius:7px}"
                                        "QRadioButton::indicator:checked {background-color:rgb(85, 170, 255);}"
                                        "QRadioButton::indicator:unchecked {background-color:rgb(255, 255, 255);}")
        self.isotp_params = {
            'stmin': 32,                          # Will request the sender to wait 32ms between consecutive frame. 0-127ms or 100-900ns with values from 0xF1-0xF9.流控帧间隔时间，0-127ms 或 100-900ns 值从 0xF1-0xF9
            'blocksize': 8,                       # Request the sender to send 8 consecutives frames before sending a new flow control message.流控帧单包大小，0表示不限制
            'wftmax': 0,                          # Number of wait frame allowed before triggering an error
            'tx_data_length': 8,                  # Link layer (CAN layer) works with 8 byte payload (CAN 2.0)
            'tx_padding': 0,                      # Will pad all transmitted CAN messages with byte 0x00. None means no padding. 当 notNone表示用于填充发送的消息的字节
            'rx_flowcontrol_timeout': 1000,        # Triggers a timeout if a flow control is awaited for more than 1000 milliseconds.在停止接收和触发之前等待流控制帧的毫秒数
            'rx_consecutive_frame_timeout': 1000,  # Triggers a timeout if a consecutive frame is awaited for more than 1000 milliseconds. 在停止接收和触发 a 之前等待连续帧的毫秒数
            'squash_stmin_requirement': False     # When sending, respect the stmin requirement of the receiver. If set to True, go as fast as possible.
            }

    # 刷新界面
    def refreshNeutral(self,int):
        self.rbt_neutral.setChecked(True if int == 1 else False)
    def refreshReverse(self,int):
        self.rbt_reverse.setChecked(True if int == 1 else False)
    def refreshPark(self,int):
        self.rbt_park.setChecked(True if int == 1 else False)
    def refreshLow(self,int):
        self.rbt_low.setChecked(True if int == 1 else False)
    def refreshHigh(self,int):
        self.rbt_high.setChecked(True if int == 1 else False)

    # 每隔300ms更新界面
    def myTimer(self):
        timer = QTimer(self)
        timer.timeout.connect(self.UI_update)
        timer.start(1000)

    def UI_update(self):
        QApplication.processEvents()  # 刷新界面
        print("界面刷新")

    # 连接通道1
    def actionChannel01_cb(self):
        # gets the connection values
        #
        baudrate = PCAN_BAUD_500K
        hwtype = PCAN_USBBUS1
        ioport = 0
        interrupt = 0

        content = self.actionChannel01.text()
        print(content)
        try:
            if content == "连接PCAN通道1":
                # Connects a selected PCAN-Basic channel
                #
                # result = self.m_objPCANBasic.Initialize(self.m_PcanHandle, baudrate, hwtype, ioport, interrupt)
                self.canbus = PcanBus(channel='PCAN_USBBUS1', bitrate=500000)  # CAN总线初始化
                result = self.m_objPCANBasic.GetStatus(PCAN_USBBUS1)
                if result == PCAN_ERROR_OK:
                    #检查CAN网络
                    self.can_message_check()
                    sleep(0.5)
                    #开启协议栈
                    self._isotpaddr_PHYS = isotp.Address(isotp.AddressingMode.Normal_11bits, txid=0x72D, rxid=0x7AD)  # 网络层寻址方法
                    self.tp_stack = isotp.CanStack(bus=self.canbus, address=self._isotpaddr_PHYS,
                                                   params=self.isotp_params)  # 网络/传输层（IsoTP 协议）
                    self.conn = PythonIsoTpConnection(self.tp_stack)  # 应用层和传输层之间建立连接

                    self.config = dict(udsoncan.configs.default_client_config)
                    self.config['security_algo'] = self.SecAlgo
                    self.config['security_algo_params'] = dict(INITIAL_REMINDER=0xFFFE)
                    self.config['data_identifiers'] = {
                        # Codec that read ASCII string. We must tell the length of the string
                        0xF180: udsoncan.AsciiCodec(10),             # boot version
                        0xF186: udsoncan.DidCodec('B'),              #当前有效诊断会话
                        0xF187: udsoncan.AsciiCodec(20),             # spare part No.
                        0xF18A: udsoncan.AsciiCodec(10),             # sys supplier
                        0xF197: udsoncan.AsciiCodec(6),              # system name.
                        0xF193: udsoncan.AsciiCodec(10),             # HW version
                        0xF195: udsoncan.AsciiCodec(10),             # SW Version
                        0xF18C: udsoncan.DidCodec('BBBBBBBBBB'),     # ECU Serial No.
                        0xF190: udsoncan.AsciiCodec(17),             # VIN
                        0xF159: udsoncan.DidCodec('B'),              # 成功编程次数
                        0xF15B: udsoncan.DidCodec('BBBBBBBBBB'),     # 软件指纹信息
                        0xF010: udsoncan.DidCodec('BBBBBBBBBBBBBBBB'),# 功能配置字
                        0xF101: udsoncan.DidCodec('BBBBBBBB'),       # 网络配置字
                        0xCF00: udsoncan.DidCodec('BB'),               # 供电电压
                        0xCF01: udsoncan.DidCodec('BB'),              # 车辆速度
                        0xCF02: udsoncan.DidCodec('BB'),              # 发动机转速
                        0xCF03: udsoncan.DidCodec('BBB'),             # 里程
                        0xCF05: udsoncan.DidCodec('BB'),              # 电机转速
                        0xCF06: udsoncan.DidCodec('BB'),              # 动力电池电压
                        0xCF07: udsoncan.DidCodec('BB'),              # 动力电池剩余电量
                        0x1600: udsoncan.DidCodec('B'),               # 按钮状态
                        0x3B90: udsoncan.DidCodec('B'),               # LED状态
                    }
                    self.config['input_output'] = {0x3B90: udsoncan.DidCodec('B'), }
                    self.config['server_address_format'] = 32
                    self.config['server_memorysize_format'] = 32
                    self.config['standard_version'] = 2006
                    # self.config['use_server_timing'] = True
                    self.config['request_timeout'] = 5
                    self.config['dtc_snapshot_did_size'] = 0x01

                    with Client(self.conn, config=self.config,request_timeout=2 ) as self.udsclient:
                        self.conn.open()  # 打开连接
                        # self.conn.close()

                    # Prepares the PCAN-Basic's PCAN-Trace file
                    self.isCh1Open = True
                    print("通道1已连接")
                    self.tb_message.setText("提示：通道1已连接！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    self.actionChannel01.setText("释放PCAN通道1")
                    if self.isCh1HasMes == True:
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append("提示：CAN通讯已连接！")
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                        self.IO_ON.setEnabled(True)
                        self.IO_OFF.setEnabled(True)
                    else:
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append("提示：电子换挡器不在线，请确保通讯正常！")
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    print("CAN Initial Error!")

            else:
                # Releases a current connected PCAN-Basic channel
                #
                if self.btn_ReadMsg.text()=="停止挡位显示":
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.setText("提示：请先停止挡位显示！")
                else:
                    if self.conn.is_open():
                        self.conn.close()

                    result = self.m_objPCANBasic.Uninitialize(PCAN_USBBUS1)

                    if result != PCAN_ERROR_OK:
                        # An error occurred, get a text describing the error and show it
                        #
                        print("Error!", self.GetFormatedError(result))
                    else:
                        self.isCh1Open = False
                        print("通道1已释放")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.setText("提示：通道1已释放！")
                        self.actionChannel01.setText("连接PCAN通道1")
                        self.lineEdit_EcuSerial.clear()
                        self.lineEdit_SparePartNum.clear()
                        self.lineEdit_VIN.clear()
                        self.rbt_park.setChecked(False)
                        self.rbt_reverse.setChecked(False)
                        self.rbt_neutral.setChecked(False)
                        self.rbt_low.setChecked(False)
                        self.rbt_high.setChecked(False)
                        self.IO_P.setChecked(False)
        except Exception as err:
            print(err)

    #确认是否有通讯
    def can_message_check(self):
        i = 0
        while (i<100):
            CANMsg = TPCANMsg()
            CANMsg.ID = 0x72D
            CANMsg.MSGTYPE = PCAN_MESSAGE_STANDARD
            CANMsg.LEN = 8
            CANMsg.DATA[0] = 0x02
            CANMsg.DATA[1] = 0x10
            CANMsg.DATA[2] = 0x01
            CANMsg.DATA[3] = 0x00
            CANMsg.DATA[4] = 0x00
            CANMsg.DATA[5] = 0x00
            CANMsg.DATA[6] = 0x00
            CANMsg.DATA[7] = 0x00
            self.WriteFrame(CANMsg)

            result = self.m_objPCANBasic.Read(self.m_PcanHandle)
            print("result[0]:", result[0])
            if result[0] == PCAN_ERROR_QRCVEMPTY:
                self.isCh1HasMes = False
                i+=1
                sleep(0.04)
                if i>=100:
                    print("无CAN通讯，请确保通讯正常")
            else:
                self.isCh1HasMes = True
                print("CAN通讯已连接")
                break

    # 开始挡位显示
    def btn_ReadMsg_cb(self):
        btn_content = self.btn_ReadMsg.text()
        if self.isCh1Open:
            if self.isCh1HasMes:
                if btn_content == "开始挡位显示":
                    self.m_Terminate = False
                    print("开启线程")
                    self.m_CanRead = True
                    self.btn_ReadMsg.setText("停止挡位显示")
                    self.m_ReadThread = threading.Thread(None, self.CANReadThreadFunc)
                    self.m_ReadThread.setDaemon(True)  #添加守护线程，当主窗口关闭时会关闭子线程
                    self.m_ReadThread.start()
                    self.m_SendThread = threading.Thread(None, self.CANSendThreadFunc)
                    self.m_SendThread.setDaemon(True)
                    self.m_SendThread.start()
                else:
                    # 将两个线程中的标志位置位，使线程终止
                    self.m_CanRead = False
                    self.m_Terminated = True
                    print("停止接收和发送线程")
                    self.btn_ReadMsg.setText("开始挡位显示")
                    self.rbt_park.setChecked(False)
                    self.rbt_reverse.setChecked(False)
                    self.rbt_neutral.setChecked(False)
                    self.rbt_low.setChecked(False)
                    self.rbt_high.setChecked(False)
                    QApplication.processEvents()  # 刷新界面
            else:
                self.tb_message.ensureCursorVisible()
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.ensureCursorVisible()
            self.tb_message.setText("提示：通道未连接！")

# -------------------------------------------------------------------------------------------------- #
    ## Thread-Function used for reading PCAN-Basic messages
    ## 数据接收线程
    def CANReadThreadFunc(self):
        try:
            self.m_Terminated = False

            # Configures the Receive-Event.
            stsResult = self.m_objPCANBasic.SetValue(self.m_PcanHandle, PCAN_RECEIVE_EVENT, self.m_ReceiveEvent)
            if stsResult != PCAN_ERROR_OK:
                print("Error: " + self.GetFormatedError(stsResult))
            else:
                while not self.m_Terminated:
                    if win32event.WaitForSingleObject(self.m_ReceiveEvent, 50) == win32event.WAIT_OBJECT_0:
                        print("开始读数据")
                        self.ReadMessages()

                # Resets the Event-handle configuration
                self.m_objPCANBasic.SetValue(self.m_PcanHandle, PCAN_RECEIVE_EVENT, 0)
        except:
            print("Error occurred while processing CAN data")

    ## Thread-Function used for reading PCAN-Basic messages
    ## 数据发送线程
    def CANSendThreadFunc(self):
        try:
            # self.m_Terminated = False
            while not self.m_Terminated:
                # if self.cb_pos_act.isChecked():
                print("开始发送数据")

                lightIndex = self.comboBox_light.currentIndex()
                lightText = self.comboBox_light.itemText(lightIndex)
                print("lightText:{}".format(lightText))
                if self.radioButton_FV.isChecked():
                    CANMsgGBC = TPCANMsg()
                    CANMsgGBC.ID = 0x129
                    CANMsgGBC.MSGTYPE = PCAN_MESSAGE_STANDARD
                    CANMsgGBC.LEN = 8
                    if lightText == "Init":
                        CANMsgGBC.DATA[0] = 0x08
                    elif lightText == "Park":
                        CANMsgGBC.DATA[0] = 0x09
                    elif lightText == "Reverse":
                        CANMsgGBC.DATA[0] = 0x0A
                    elif lightText == "Neutral":
                        CANMsgGBC.DATA[0] = 0x0B
                    elif lightText == "Low":
                        CANMsgGBC.DATA[0] = 0x0C
                    elif lightText == "High":
                        CANMsgGBC.DATA[0] = 0x0D
                    elif lightText == "Moto_running/Reserved":
                        CANMsgGBC.DATA[0] = 0x0E
                    CANMsgGBC.DATA[1] = 0x00
                    CANMsgGBC.DATA[2] = 0x00
                    CANMsgGBC.DATA[3] = 0x00
                    CANMsgGBC.DATA[4] = 0x00
                    CANMsgGBC.DATA[5] = 0x00
                    CANMsgGBC.DATA[6] = 0x00
                    CANMsgGBC.DATA[7] = 0x00
                    self.WriteFrame(CANMsgGBC)
                    sleep(0.02)

                if self.radioButton_EV.isChecked():
                    CANMsgBCM = TPCANMsg()
                    CANMsgBCM.ID = 0x10D
                    CANMsgBCM.MSGTYPE = PCAN_MESSAGE_STANDARD
                    CANMsgBCM.LEN = 8
                    if lightText == "Init":
                        CANMsgBCM.DATA[0] = 0x02
                    elif lightText == "Park":
                        CANMsgBCM.DATA[0] = 0x06
                    elif lightText == "Reverse":
                        CANMsgBCM.DATA[0] = 0x0A
                    elif lightText == "Neutral":
                        CANMsgBCM.DATA[0] = 0x0E
                    elif lightText == "Low":
                        CANMsgBCM.DATA[0] = 0x12
                    elif lightText == "High":
                        CANMsgBCM.DATA[0] = 0x16
                    elif lightText == "Moto_running/Reserved":
                        CANMsgBCM.DATA[0] = 0x1A
                    CANMsgBCM.DATA[1] = 0x80
                    CANMsgBCM.DATA[2] = 0x00
                    CANMsgBCM.DATA[3] = 0x00
                    CANMsgBCM.DATA[4] = 0x00
                    CANMsgBCM.DATA[5] = 0x00
                    CANMsgBCM.DATA[6] = 0x00
                    CANMsgBCM.DATA[7] = 0x00
                    self.WriteFrame(CANMsgBCM)
                    sleep(0.02)
                    print("send BCM info!")

                CANMsgBKLight = TPCANMsg()
                CANMsgBKLight.ID = 0x207
                CANMsgBKLight.MSGTYPE = PCAN_MESSAGE_STANDARD
                CANMsgBKLight.LEN = 8
                if self.radioButton_BKON.isChecked():
                    CANMsgBKLight.DATA[0] = 0x40
                elif self.radioButton_BKOFF.isChecked():
                    CANMsgBKLight.DATA[0] = 0x00
                CANMsgBKLight.DATA[1] = 0x00
                CANMsgBKLight.DATA[2] = 0x00
                CANMsgBKLight.DATA[3] = 0x00
                CANMsgBKLight.DATA[4] = 0x00
                CANMsgBKLight.DATA[5] = 0x00
                CANMsgBKLight.DATA[6] = 0x00
                CANMsgBKLight.DATA[7] = 0x00
                self.WriteFrame(CANMsgBKLight)
                sleep(0.02)
        except:
            print("Error occurred while sending CAN data")

    ## Help Function used to get an error as text
    ## 故障检测
    def GetFormatedError(self, error):
        # Gets the text using the GetErrorText API function
        # If the function success, the translated error is returned. If it fails,
        # a text describing the current error is returned.
        #
        stsReturn = self.m_objPCANBasic.GetErrorText(error, 0)
        if stsReturn[0] != PCAN_ERROR_OK:
            return "An error occurred. Error-code's text ({0:X}h) couldn't be retrieved".format(error)
        else:
            return stsReturn[1]

    def tmrRead_Tick(self):
        # Checks if in the receive-queue are currently messages for read
        #
        self.ReadMessages()

    ## Function for reading CAN messages on normal CAN devices
    ## 读报文
    def ReadMessages(self):
        stsResult = PCAN_ERROR_OK

        # We read at least one time the queue looking for messages.
        # If a message is found, we look again trying to find more.
        # If the queue is empty or an error occurr, we get out from
        # the dowhile statement.
        #
        while (self.m_CanRead and not (stsResult & PCAN_ERROR_QRCVEMPTY)):

            stsResult = self.ReadMessage()

            if stsResult == PCAN_ERROR_ILLOPERATION:
                break

    def ReadMessage(self):
        # We execute the "Read" function of the PCANBasic
        #
        result = self.m_objPCANBasic.Read(self.m_PcanHandle)
        print("result[0]:",result[0])

        if result[0] == PCAN_ERROR_OK:
            # We show the received message
            #
            revMsg = self.ProcessMessage(result[1:])
            # 如果挡位接收使能打开，则判断挡位
            # if self.cb_pos_act.isChecked():
            self.LeverPosition(revMsg)

        return result[0]

    ## Processes a received message, in order to show it in the Message-ListView
    ## 报文处理
    def ProcessMessage(self, *args):
        with self._lock:
            canMsg = []
            # Split the arguments. [0] TPCANMsg, [1] TPCANTimestamp
            #
            theMsg = args[0][0]
            itsTimeStamp = args[0][1]

            newMsg = TPCANMsg()
            newMsg.ID = theMsg.ID
            newMsg.DLC = theMsg.LEN
            canMsg.append(hex(newMsg.ID))
            for i in range(8):
                newMsg.DATA[i] = theMsg.DATA[i]
                canMsg.append(''.join(hex(theMsg.DATA[i])).replace("0x", '').zfill(2))
            newMsg.MSGTYPE = theMsg.MSGTYPE
            print(canMsg)

            newTimestamp = TPCANTimestamp()
            newTimestamp.value = (itsTimeStamp.micros + 1000 * itsTimeStamp.millis + 0x100000000 * 1000 * itsTimeStamp.millis_overflow)
            return newMsg

    # 判断挡杆位置
    def LeverPosition(self, msg):
        CANMsg = msg
        if (CANMsg.ID == 0x102):
            if (((CANMsg.DATA[0])>>0x3) & 0x1 == 0x01):
                print("Park按钮按下")
                self.position_park = 1
            else:
                # print("Park按钮未按下")
                self.position_park = 0

            if (((CANMsg.DATA[0])>>0x5)&0x7 == 0x1):
                print("Reverse")
                self.position_reverse = 1
            elif (((CANMsg.DATA[0])>>0x5)&0x7 == 0x2):
                print("Neutral")
                self.position_neutral = 1
            elif (((CANMsg.DATA[0])>>0x5)&0x7 == 0x3):
                print("LOW")
                self.position_low = 1
            elif (((CANMsg.DATA[0])>>0x5)&0x7 == 0x4):
                print("High")
                self.position_high = 1
            else:
                self.position_reverse = 0
                self.position_neutral = 0
                self.position_high = 0
                self.position_low = 0

            UI_SIGNAL.park.emit(self.position_park)
            UI_SIGNAL.reverse.emit(self.position_reverse)
            UI_SIGNAL.neutral.emit(self.position_neutral)
            UI_SIGNAL.high.emit(self.position_high)
            UI_SIGNAL.low.emit(self.position_low)


    # 发送报文
    def WriteFrame(self, msg):
        CANMsg = msg

        # The message is sent to the configured hardware
        result = self.m_objPCANBasic.Write(self.m_PcanHandle, CANMsg)
        if result != PCAN_ERROR_OK:
            # An error occurred, get a text describing the error and show it
            #
            ret = self.m_objPCANBasic.GetErrorText(result)
            print(ret[1])
        else:
            print("Message sent successfully")
            return result

    # 读取一帧报文
    def ReadSingleMsg(self):
        try:
            # self.CANMsgFilter()
            result = self.m_objPCANBasic.Read(self.m_PcanHandle)
            if result[0] == PCAN_ERROR_OK:
                # We show the received message
                canMsg = []
                # Split the arguments. [0] TPCANMsg, [1] TPCANTimestamp
                theMsg = result[1]

                newMsg = TPCANMsg()
                newMsg.ID = theMsg.ID
                newMsg.DLC = theMsg.LEN
                canMsg.append(hex(newMsg.ID))
                for i in range(8):
                    newMsg.DATA[i] = theMsg.DATA[i]
                    canMsg.append(''.join(hex(theMsg.DATA[i])).replace("0x", '').zfill(2))
                newMsg.MSGTYPE = theMsg.MSGTYPE
                print(canMsg)

                return theMsg
        except:
                # An error occurred, get a text describing the error and show it#
                resultERR = self.m_objPCANBasic.GetErrorText(result[0])
                print(resultERR[1])
                # return
                # self.HandleReadError(result[0])  # Possible errors handling function, HandleError(function_result)

    # 设定报文滤波
    def CANMsgFilter(self):
        #  The message filter is closed first to ensure the reception of the new range of IDs.
        #
        result = self.m_objPCANBasic.SetValue(PCAN_USBBUS1, PCAN_MESSAGE_FILTER, PCAN_FILTER_CLOSE)
        if result != PCAN_ERROR_OK:
            # An error occurred, get a text describing the error and show it
            #
            result = self.m_objPCANBasic.GetErrorText(result)
            print(result[1])
        else:
            # The message filter is configured to receive the IDs 2,3,4 and 5 on the PCAN-USB, Channel 1
            #
            result = self.m_objPCANBasic.FilterMessages(PCAN_USBBUS1, 0x7d0, 0x7d8, PCAN_MODE_STANDARD)
            if result != PCAN_ERROR_OK:
                # An error occurred, get a text describing the error and show it
                #
                result = self.m_objPCANBasic.GetErrorText(result)
                print(result[1])
            else:
                print("Filter successfully configured for IDs from 7D0 to 7D8.")

    def ResetBuffer(self):
            # The PCI Channel is released
            #
            result = self.m_objPCANBasic.Reset(PCAN_PCIBUS1)
            if result != PCAN_ERROR_OK:
                # An error occurred, get a text describing the error and show it
                #
                result = self.m_objPCANBasic.GetErrorText(result)
                print(result[1])
            else:
                print("PCAN-PCI (Ch-1) was reset")

#---------------------------------------------------------------------------------------#
    # 读取配置信息
    def ReadNetConfig(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取网络配置信息")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF101])
                        UDS_str = resp.service_data.values[0xF101]
                        config_data = UDS_str[5]&0x1
                        if config_data == 0:
                            config_str = "EV"
                        elif config_data == 1:
                            config_str = "FV"
                        else:
                            config_str = "无效车型"
                        print("UDS_str",UDS_str)
                        print('UDS发送请求成功')
                        self.conn.close()
                        # 硬件版本号
                        self.tb_message.append("配置信息如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append("  配置信息为："+str(UDS_str))
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append("  配置车型为："+config_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '配置信息读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取硬件版本
    def ReadHWVersion(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取硬件版本")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF193])
                        UDS_str = resp.service_data.values[0xF193]
                        print('UDS发送请求成功')
                        self.conn.close()
                        # 硬件版本号
                        self.tb_message.append("硬件版本号如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '零件硬件版本读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取VIN码
    def ReadVINCode(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读VIN")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        # self.udsclient.change_session(3)  # 10 03
                        resp = self.udsclient.read_data_by_identifier([0xF190])
                        UDS_data = resp.service_data.values[0xF190]
                        print('UDS发送请求成功')
                        self.conn.close()
                        # VIN
                        self.tb_message.append("车辆识别号VIN码如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_data)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', 'VIN码读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取系统电压
    def ReadPower(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取系统电压")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xCF00])
                        sysPower = resp.service_data.values[0xCF00]
                        print('UDS发送请求成功')
                        print(sysPower)
                        # print("sysPower",sysPower)
                        sys_power = ((sysPower[0]<<8)+sysPower[1])/100+3
                        sys_power = round((sys_power),2)
                        # print("sys_ower", sys_power)
                        self.conn.close()
                        # 硬件版本号
                        self.tb_message.append("系统电压为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(sys_power)+"V")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '系统电压读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    #读取成功编程次数
    def ReadProgrammingCount(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读编程次数")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF159])
                        promCountData = resp.service_data.values[0xF159]
                        promCount = promCountData[0]
                        self.conn.close()
                        # 硬件版本号
                        self.tb_message.append("成功编程次数为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(promCount)+"次")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '成功编程次数读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取车速
    def ReadVehicleSpeed(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取车速信息")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xCF01])
                        vehicleData = resp.service_data.values[0xCF01]
                        print('vehicleData=',vehicleData)
                        vehicleSpeed = ((vehicleData[0]<<8)+vehicleData[1])*0.05625
                        vehicleSpeedRod = round((vehicleSpeed),2)
                        self.conn.close()

                        self.tb_message.append("车辆速度为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(vehicleSpeedRod)+"Km/h")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '车辆速度为读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取发动机转速
    def ReadEngineSpeed(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取发动机转速")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xCF02])
                        EngineerSpdData = resp.service_data.values[0xCF02]
                        print("EngineerSpdData=",EngineerSpdData)
                        EngineerSpd = ((EngineerSpdData[0]<<8) + EngineerSpdData[1])*0.25
                        EngineerSpdRod = round((EngineerSpd), 2)
                        self.conn.close()

                        self.tb_message.append("发动机转速为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(EngineerSpdRod) + "RPM")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '发动机转速读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    #读取里程数据
    def ReadOdoMeter(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取里程数据")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xCF03])
                        OdoData = resp.service_data.values[0xCF03]
                        print("OdoData=",OdoData)
                        Odometer = ((OdoData[0]<<16) + (OdoData[1]<<8)+OdoData[0])*0.1
                        OdometerRod = round((Odometer), 1)
                        self.conn.close()

                        self.tb_message.append("行驶里程为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(OdometerRod) + "km")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '行驶里程读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)
    #读取电机转速
    def ReadMotoSpeed(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取电机转速")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xCF05])
                        motoSpdData = resp.service_data.values[0xCF05]
                        print("motoSpdData=",motoSpdData)
                        motoSpd = ((motoSpdData[0]<<8)+motoSpdData[1])-20000
                        self.conn.close()

                        self.tb_message.append("电机转速为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(motoSpd) + "rpm")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '电机转速读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    #读取动力电池电压
    def ReadTotalPower(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取动力电池电压")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xCF06])
                        totalPowerData = resp.service_data.values[0xCF06]
                        print("totalPowerData=",totalPowerData)
                        totalPower = ((totalPowerData[0]<<8)+totalPowerData[1])*0.1
                        totalPowerRod = round((totalPower), 1)
                        self.conn.close()

                        self.tb_message.append("动力电池总电压为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(totalPowerRod) + "V")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '动力电池总电压读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    #读取动力电池剩余电量
    def ReadSOC(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取动力电池剩余电量")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xCF07])
                        SOCData = resp.service_data.values[0xCF07]
                        print("SOCData=",SOCData)
                        SOC = ((SOCData[0]<<8)+SOCData[1])*0.1
                        SOCRod = round((SOC), 1)
                        self.conn.close()

                        self.tb_message.append("动力电池剩余电量为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(SOCRod) + "%")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '动力电池剩余电量读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)
    # 读取按钮状态
    def ReadButtonState(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取按钮状态")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0x1600])
                        UDS_Data = resp.service_data.values[0x1600]
                        ParkState = UDS_Data[0] & 0x1
                        ReverseState = (UDS_Data[0] >> 1) & 0x1
                        NeutralState = (UDS_Data[0] >> 2) & 0x1
                        HighStatus = (UDS_Data[0] >> 3) & 0x1
                        LowStatus = (UDS_Data[0] >> 4) & 0x1

                        self.conn.close()
                        # 传感器状态
                        self.tb_message.append("按钮状态如下：")
                        self.tb_message.ensureCursorVisible()
                        if ParkState == 0x1:
                            self.tb_message.append("--Park Button-----已激活")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Park Button-----未激活")
                            self.tb_message.ensureCursorVisible()
                        if ReverseState == 0x1:
                            self.tb_message.append("--Reverse Button--已激活")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Reverse Button--未激活")
                            self.tb_message.ensureCursorVisible()
                        if NeutralState == 0x1:
                            self.tb_message.append("--Neutral Button--已激活")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Neutral Button--未激活")
                            self.tb_message.ensureCursorVisible()
                        if HighStatus == 0x1:
                            self.tb_message.append("--High Button-----已激活")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--High Button-----未激活")
                            self.tb_message.ensureCursorVisible()
                        if LowStatus == 0x1:
                            self.tb_message.append("--Low Button------已激活")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Low Button------未激活")
                            self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                        self.tb_message.append("-------------------------")
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '按钮状态读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)
    #读LED状态
    def ReadLedState(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取LED状态")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        # self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0x3B90])
                        UDS_Data = resp.service_data.values[0x3B90]
                        print("LED status:",UDS_Data[0])
                        PLedState = UDS_Data[0] & 0x1
                        RLedState = (UDS_Data[0] >> 1) & 0x1
                        NLedState = (UDS_Data[0] >> 2) & 0x1
                        HLedStatus = (UDS_Data[0] >> 3) & 0x1
                        LLedStatus = (UDS_Data[0] >> 4) & 0x1
                        BKLedStatus = (UDS_Data[0] >> 5) & 0x1
                        self.conn.close()
                        # 传感器状态
                        self.tb_message.append("LED状态如下：")
                        self.tb_message.ensureCursorVisible()
                        if PLedState == 0x1:
                            self.tb_message.append("--Park LED-------已点亮")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Park LED-------未点亮")
                            self.tb_message.ensureCursorVisible()
                        if RLedState == 0x1:
                            self.tb_message.append("--Reverse LED----已点亮")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Reverse LED----未点亮")
                            self.tb_message.ensureCursorVisible()
                        if NLedState == 0x1:
                            self.tb_message.append("--Neutral LED----已点亮")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Neutral LED----未点亮")
                            self.tb_message.ensureCursorVisible()
                        if HLedStatus == 0x1:
                            self.tb_message.append("--High LED-------已点亮")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--High LED-------未点亮")
                            self.tb_message.ensureCursorVisible()
                        if LLedStatus == 0x1:
                            self.tb_message.append("--Low LED--------已点亮")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Low LED--------未点亮")
                            self.tb_message.ensureCursorVisible()
                        if BKLedStatus == 0x1:
                            self.tb_message.append("--Backlight LED--已点亮")
                            self.tb_message.ensureCursorVisible()
                        else:
                            self.tb_message.append("--Backlight LED--未点亮")
                            self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                        self.tb_message.append("-------------------------")
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', 'LED状态读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)
    # 读取软件版本
    def ReadSWVersion(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF195])
                        UDS_str = resp.service_data.values[0xF195]
                        print('UDS发送请求成功')
                        self.conn.close()
                        # 软件版本号
                        self.tb_message.append("软件版本号如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '零件软件版本读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)


    # 读取编程日期
    def ReadProgrammingDate(self):
        print("开始读编程日期")
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接

                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF199])
                        UDS_str = resp.service_data.values[0xF199]
                        print(UDS_str)
                        print('UDS发送请求成功')
                        self.conn.close()
                        # 软件版本号
                        self.tb_message.append("编程日期如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        qw.QMessageBox.information(self, '信息', '编程日期读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取BOOT版本
    def ReadBOOTVersion(self):
        print("开始读取BOOT版本")
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)  # 10 01
                        resp = self.udsclient.read_data_by_identifier([0xF180])
                        UDS_str = resp.service_data.values[0xF180]
                        print('UDS发送请求成功')
                        self.conn.close()
                        # 软件版本号
                        self.tb_message.append("BOOT版本号如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        qw.QMessageBox.information(self, '信息', 'BOOT版本读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取Spare Part Number
    def ReadSparePartNum(self):
        print("开始读取spare part num")
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF187])
                        UDS_str = resp.service_data.values[0xF187]
                        print('UDS发送请求成功')
                        self.conn.close()
                        # Spare Part Number
                        self.tb_message.append("零件号如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        qw.QMessageBox.information(self, '信息', '零件号读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取Serial Number
    def ReadSerialNum(self):
        print("开始读取Serial number")
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF18C])
                        UDS_BCD = resp.service_data.values[0xF18C]
                        print("UDS_BCD=",UDS_BCD)
                        #将BCD码按高低位拆分并转换为字符串进行拼接
                        UDS_str = str((UDS_BCD[0]>>4)&0xF)+str(UDS_BCD[0]&0xF)\
                                  +str((UDS_BCD[1]>>4)&0xF)+str(UDS_BCD[1]&0xF)\
                                  +str((UDS_BCD[2]>>4)&0xF)+str(UDS_BCD[2]&0xF)\
                                  +str((UDS_BCD[3]>>4)&0xF)+str(UDS_BCD[3]&0xF)\
                                  +str((UDS_BCD[4]>>4)&0xF)+str(UDS_BCD[4]&0xF)\
                                  +str((UDS_BCD[5]>>4)&0xF)+str(UDS_BCD[5]&0xF)\
                                  +str((UDS_BCD[6]>>4)&0xF)+str(UDS_BCD[6]&0xF)\
                                  +str((UDS_BCD[7]>>4)&0xF)+str(UDS_BCD[7]&0xF)\
                                  +str((UDS_BCD[8]>>4)&0xF)+str(UDS_BCD[8]&0xF)\
                                  +str((UDS_BCD[9]>>4)&0xF)+str(UDS_BCD[9]&0xF)
                        print('UDS发送请求成功')
                        self.conn.close()
                        # Spare Part Number
                        self.tb_message.append("序列号如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        qw.QMessageBox.information(self, '信息', '序列号读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取供应商代码
    def ReadSupplierNum(self):
        print("开始读取供应商代码")
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接

                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF18A])
                        UDS_str = resp.service_data.values[0xF18A]
                        print('UDS发送请求成功')
                        self.conn.close()

                        # 输出信息
                        self.tb_message.append("供应商代码如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(UDS_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        qw.QMessageBox.information(self, '信息', '供应商代码读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    def ReadFingerPrint(self):
        print("开始读取软件指纹信息")
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF15B])
                        UDS_data = resp.service_data.values[0xF15B]
                        print('UDS_data=',UDS_data)
                        uds_str = str(UDS_data[0])+str((UDS_data[1]>>4)&0xF)+str(UDS_data[1]&0xF)+str((UDS_data[2]>>4)&0xF)+str(UDS_data[2]&0xF)\
                                  +str((UDS_data[3]>>4)&0xF)+str(UDS_data[3]&0xF)+str(UDS_data[4])+str(UDS_data[5])+str(UDS_data[6])+str(UDS_data[7])+\
                                  str(UDS_data[8])+str(UDS_data[9])
                        self.conn.close()
                        # 输出信息
                        self.tb_message.append("软件指纹信息如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(uds_str)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        qw.QMessageBox.information(self, '信息', '软件指纹信息读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    def ReadActiveSession(self):
        print("开始读取当前有效诊断会话")
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        # self.udsclient.change_session(1)
                        resp = self.udsclient.read_data_by_identifier([0xF186])
                        UDS_data = resp.service_data.values[0xF186]
                        print("UDS_data=",UDS_data)
                        if UDS_data[0] == 1:
                            session = '默认会话'
                        elif UDS_data[0] == 2:
                            session = '编程会话'
                        elif UDS_data[0] == 3:
                            session = '扩展会话'
                        self.conn.close()
                        # 输出信息
                        self.tb_message.append("当前有效诊断会话为：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append(str(UDS_data[0])+":"+session)
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        qw.QMessageBox.information(self, '信息', '当前有效诊断会话读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取当前故障内容
    def ReadCurrentDTC(self):
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        response = self.udsclient.get_dtc_by_status_mask(1)
                        DTC_codes = response.service_data.dtcs
                    except:
                        qw.QMessageBox.information(self, '信息', '当前故障读取失败')

                    self.conn.close()
                    self.tb_message.append("当前故障如下：")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    self.show_DTC(DTC_codes)
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 读取历史故障内容
    def ReadHistoryDTC(self):
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接

                    try:
                        self.udsclient.change_session(1)
                        response = self.udsclient.get_dtc_by_status_mask(8)
                        DTC_codes = response.service_data.dtcs
                        print("DTC_codes",DTC_codes)

                    except:
                        qw.QMessageBox.information(self, '信息', '历史故障读取失败')

                    self.tb_message.append("历史故障如下：")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    self.show_DTC(DTC_codes)
                    self.conn.close()
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    def GetDTCSnapShotNo(self):
        snapShotIndex = self.comboBox_SnapShotList.currentIndex()
        snapShotText = self.comboBox_SnapShotList.itemText(snapShotIndex)
        if snapShotText == "UC07388:CAN busoff FV":
            dtcNo = 0xC07388
        elif snapShotText == "UC07388:CAN busoff EV":
            dtcNo = 0xC07488
        elif snapShotText == "B111716:系统供电电压过低":
            dtcNo = 0x911716
        elif snapShotText == "B111717:系统供电电压过高":
            dtcNo = 0x911717
        elif snapShotText == "U220D00:网络管理跛行回家故障":
            dtcNo = 0xE20D00
        elif snapShotText == "P16019E:P按钮卡滞":
            dtcNo = 0x16019E
        elif snapShotText == "P16029E:R按钮卡滞":
            dtcNo = 0x16029E
        elif snapShotText == "P16039E:N按钮卡滞":
            dtcNo = 0x16039E
        elif snapShotText == "P16049E:H按钮卡滞":
            dtcNo = 0x16049E
        elif snapShotText == "P16059E:L按钮卡滞":
            dtcNo = 0x16059E
        elif snapShotText == "U010087:ECM节点通讯丢失":
            dtcNo = 0xC10087
        elif snapShotText == "U120682:ECM节点Rolling counter错误":
            dtcNo = 0xD20682
        elif snapShotText == "U140683:ECM节点Checksum错误":
            dtcNo = 0xD40683
        elif snapShotText == "U11C087:BCM节点通讯丢失":
            dtcNo = 0xD1C087
        elif snapShotText == "U121582:BCM节点Rolling counter错误":
            dtcNo = 0xD21582
        elif snapShotText == "U141583:BCM节点Checksum错误":
            dtcNo = 0xD41583
        elif snapShotText == "U118287:MMI节点通讯丢失":
            dtcNo = 0xD18287
        elif snapShotText == "U118187:DASH节点通讯丢失":
            dtcNo = 0xD18187
        elif snapShotText == "U111087:GBC节点通讯丢失":
            dtcNo = 0xD11087
        elif snapShotText == "U121482:GBC节点Rolling counter错误":
            dtcNo = 0xD21482
        elif snapShotText == "U141583:GBC节点Checksum错误":
            dtcNo = 0xD41483
        elif snapShotText == "U110087:VCU节点通讯丢失":
            dtcNo = 0xD10087
        elif snapShotText == "U120F82:VCU节点Rolling counter错误":
            dtcNo = 0xD20F82
        elif snapShotText == "U140F83:VCU节点Checksum错误":
            dtcNo = 0xD20F83
        elif snapShotText == "U110587:MCU节点通讯丢失":
            dtcNo = 0xD10587
        elif snapShotText == "U120582:MCU节点Rolling counter错误":
            dtcNo = 0xD20582
        elif snapShotText == "U140583:MCU节点Checksum错误":
            dtcNo = 0xD10487
        elif snapShotText == "U110487:BMS节点通讯丢失":
            dtcNo = 0xD10587
        elif snapShotText == "U120982:BMS节点Rolling counter错误":
            dtcNo = 0xD20982
        elif snapShotText == "U140983:BMS节点Checksum错误":
            dtcNo = 0xD40983
        elif snapShotText == "U120B82:ECM_DrvInfo节点Rolling counter错误":
            dtcNo = 0xD20B82
        elif snapShotText == "U140B83:ECM_DrvInfo节点Checksum错误":
            dtcNo = 0xD40B83
        return dtcNo

    # 读取故障快照
    def ReadSnapShot(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始故障快照")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接

                    try:
                        self.udsclient.change_session(1)
                        currentDtcNo = self.GetDTCSnapShotNo()
                        DtcNo = int(currentDtcNo)
                        print("当前读取的DTC为：", DtcNo, type(DtcNo))
                        resp = self.udsclient.get_dtc_snapshot_by_dtc_number(DtcNo, 0XFF)
                        print("resp.data=",resp.data)
                        # for i in range (len(resp.data)):
                        #     print(hex(resp.data[i]))
                        resp01 = self.udsclient.read_data_by_identifier([0xF101])
                        UDS_str_confg = resp01.service_data.values[0xF101]
                        config_data = UDS_str_confg[5]&0x1
                        if config_data == 0:
                            config_str = "EV"
                        elif config_data == 1:
                            config_str = "FV"
                        else:
                            config_str = "无效车型"
                        self.showDtcSnapShot(resp.data,config_str)
                        self.conn.close()
                        #
                        # self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '故障快照读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    #读取扩展数据
    def ReadExtendData(self):
        if self.isCh1Open == True:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("开始读取扩展数据")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        currentDtcNo = self.GetDTCSnapShotNo()
                        DtcNo = int(currentDtcNo)
                        print("当前读取的DTC为：", DtcNo, type(DtcNo))
                        resp = self.udsclient.get_dtc_extended_data_by_dtc_number(DtcNo, 0XFF,2)
                        print("resp.data=",resp.data)
                        for i in range (len(resp.data)):
                            print(hex(resp.data[i]))
                        # self.showDtcSnapShot(resp.data)
                        self.tb_message.append("故障扩展数据如下：")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append("故障发生次数为："+str(resp.data[6])+"次")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.append("故障挂起次数为："+str(resp.data[8])+"次")
                        self.tb_message.ensureCursorVisible()
                        self.conn.close()

                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    except:
                        print('UDS发送请求失败')
                        qw.QMessageBox.information(self, '信息', '故障扩展数据读取失败')
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 擦除诊断信息
    def btn_eraseDTC_cb(self):
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    choice = qw.QMessageBox.question(self, '确认', '确定要清除故障吗？')
                    if choice == qw.QMessageBox.Yes:
                        print('你选择了yes')
                        try:
                            response = self.udsclient.clear_dtc(0xFFFFFF)
                            if response.positive:
                                self.tb_message.append("故障已清除！")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            else:
                                self.tb_message.append("故障清除失败！")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            self.conn.close()
                        except:
                            qw.QMessageBox.information(self, '信息', '清除故障失败！')

                    if choice == qw.QMessageBox.No:
                        print('你选择了no')
                        self.tb_message.append("不清除故障！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：请先停止挡位通讯！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 清空显示在界面上的信息
    def btn_clearDTC_cb(self):
        self.tb_message.clear()
        self.tb_message.moveCursor(self.tb_message.textCursor().End)

    def IO_P_cb(self):
        if self.IO_P.isChecked():
            if self.isCh1Open:
                if self.isCh1HasMes:
                    if self.m_CanRead == False:
                        if self.IO_ON.isChecked():
                            if not self.conn.is_open():
                                self.conn.open()  # 打开连接
                            try:
                                self.udsclient.change_session(1)
                                self.udsclient.change_session(3)
                                self.udsclient.unlock_security_access(1)
                                self.udsclient.io_control(0x3B90,3,[1,])
                                self.conn.close()
                                # 输出信息
                                self.tb_message.append("Park LED ON.")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            except:
                                qw.QMessageBox.information(self, '信息', 'Park LED点亮失败')
                        else:
                            self.tb_message.append("提示：IO ON 未勾选！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        self.tb_message.append("提示：请先停止挡位显示！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：CAN网络上没有报文！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：通道未打开，请先打开通道！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("P is not checked")

    def IO_R_cb(self):
        if self.IO_R.isChecked():
            if self.isCh1Open:
                if self.isCh1HasMes:
                    if self.m_CanRead == False:
                        if self.IO_ON.isChecked():
                            if not self.conn.is_open():
                                self.conn.open()  # 打开连接
                            try:
                                self.udsclient.change_session(1)
                                self.udsclient.change_session(3)
                                self.udsclient.unlock_security_access(1)
                                self.udsclient.io_control(0x3B90,3,[2,])
                                self.conn.close()
                                # 输出信息
                                self.tb_message.append("Reverse LED ON.")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            except:
                                qw.QMessageBox.information(self, '信息', 'Reverse LED点亮失败')
                        else:
                            self.tb_message.append("提示：IO ON 未勾选！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        self.tb_message.append("提示：请先停止挡位显示！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：CAN网络上没有报文！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：通道未打开，请先打开通道！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("R is not checked")
    def IO_N_cb(self):
        if self.IO_N.isChecked():
            if self.isCh1Open:
                if self.isCh1HasMes:
                    if self.m_CanRead == False:
                        if self.IO_ON.isChecked():
                            if not self.conn.is_open():
                                self.conn.open()  # 打开连接
                            try:
                                self.udsclient.change_session(1)
                                self.udsclient.change_session(3)
                                self.udsclient.unlock_security_access(1)
                                self.udsclient.io_control(0x3B90,3,[4,])
                                self.conn.close()
                                # 输出信息
                                self.tb_message.append("Reverse LED ON.")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            except:
                                qw.QMessageBox.information(self, '信息', 'Neutral LED点亮失败')
                        else:
                            self.tb_message.append("提示：IO ON 未勾选！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        self.tb_message.append("提示：请先停止挡位显示！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：CAN网络上没有报文！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：通道未打开，请先打开通道！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("N is not checked")
    def IO_L_cb(self):
        if self.IO_L.isChecked():
            if self.isCh1Open:
                if self.isCh1HasMes:
                    if self.m_CanRead == False:
                        if self.IO_ON.isChecked():
                            if not self.conn.is_open():
                                self.conn.open()  # 打开连接
                            try:
                                self.udsclient.change_session(1)
                                self.udsclient.change_session(3)
                                self.udsclient.unlock_security_access(1)
                                self.udsclient.io_control(0x3B90,3,[8,])
                                self.conn.close()
                                # 输出信息
                                self.tb_message.append("Low LED ON.")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            except:
                                qw.QMessageBox.information(self, '信息', 'Low LED点亮失败')
                        else:
                            self.tb_message.append("提示：IO ON 未勾选！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        self.tb_message.append("提示：请先停止挡位显示！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：CAN网络上没有报文！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：通道未打开，请先打开通道！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("L is not checked")
    def IO_H_cb(self):
        if self.IO_H.isChecked():
            if self.isCh1Open:
                if self.isCh1HasMes:
                    if self.m_CanRead == False:
                        if self.IO_ON.isChecked():
                            if not self.conn.is_open():
                                self.conn.open()  # 打开连接
                            try:
                                self.udsclient.change_session(1)
                                self.udsclient.change_session(3)
                                self.udsclient.unlock_security_access(1)
                                self.udsclient.io_control(0x3B90,3,[16,])
                                self.conn.close()
                                # 输出信息
                                self.tb_message.append("High LED ON.")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            except:
                                qw.QMessageBox.information(self, '信息', 'High LED点亮失败')
                        else:
                            self.tb_message.append("提示：请先停止挡位显示！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        self.tb_message.append("提示：IO ON 未勾选！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：CAN网络上没有报文！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：通道未打开，请先打开通道！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("H is not checked")
    def IO_BK_cb(self):
        if self.IO_BK.isChecked():
            if self.isCh1Open:
                if self.isCh1HasMes:
                    if self.m_CanRead == False:
                        if self.IO_ON.isChecked():
                            if not self.conn.is_open():
                                self.conn.open()  # 打开连接
                            try:
                                self.udsclient.change_session(1)
                                self.udsclient.change_session(3)
                                self.udsclient.unlock_security_access(1)
                                self.udsclient.io_control(0x3B90,3,[32,])
                                self.conn.close()
                                # 输出信息
                                self.tb_message.append("Backlight LED ON.")
                                self.tb_message.ensureCursorVisible()
                                self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            except:
                                qw.QMessageBox.information(self, '信息', 'Backlight LED点亮失败')
                        else:
                            self.tb_message.append("提示：IO ON 未勾选！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        self.tb_message.append("提示：请先停止挡位显示！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：CAN网络上没有报文！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：通道未打开，请先打开通道！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("BK is not checked")

    def IO_ON_cb(self):
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    self.IO_BK.setEnabled(True)
                    self.IO_P.setEnabled(True)
                    self.IO_R.setEnabled(True)
                    self.IO_N.setEnabled(True)
                    self.IO_L.setEnabled(True)
                    self.IO_H.setEnabled(True)
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.IO_ON.setChecked(False)
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    def IO_OFF_cb(self):
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    if self.IO_OFF.isChecked():
                        if not self.conn.is_open():
                            self.conn.open()  # 打开连接
                        try:
                            self.udsclient.change_session(1)
                            self.udsclient.change_session(3)
                            self.udsclient.unlock_security_access(1)
                            self.udsclient.io_control(0x3B90,0)
                            self.conn.close()
                            # 输出信息
                            self.tb_message.append("IO LED Control OFF.")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            self.IO_BK.setChecked(False)
                            self.IO_P.setChecked(False)
                            self.IO_R.setChecked(False)
                            self.IO_N.setChecked(False)
                            self.IO_L.setChecked(False)
                            self.IO_H.setChecked(False)
                            self.IO_BK.setEnabled(False)
                            self.IO_P.setEnabled(False)
                            self.IO_R.setEnabled(False)
                            self.IO_N.setEnabled(False)
                            self.IO_L.setEnabled(False)
                            self.IO_H.setEnabled(False)
                        except:
                            qw.QMessageBox.information(self, '信息', 'IO LED Control失败')
                    else:
                        print("IO ON")
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            self.tb_message.append("提示：通道未打开，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    #写序列号
    def WriteEcuNo(self):
        EcuSerialNoIntList = [0,0,0,0,0,0,0,0,0,0]
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("写入序列号")
                    EcuSerialNoStr = self.lineEdit_EcuSerial.text() #读取字符串
                    print("EcuSerialNoStr=",EcuSerialNoStr)

                    if len(EcuSerialNoStr) == 20: #判断是否是20位
                        # if len(EcuSerialNoStr)<10:
                        #     EcuSerialNoStr += (10-len(EcuSerialNoStr))*" "
                        #转化为整型并将高低位拼接在一起放入一个列表
                        EcuSerialNoIntList[0] = (int(EcuSerialNoStr[0]) << 4) + int(EcuSerialNoStr[1])
                        EcuSerialNoIntList[1] = (int(EcuSerialNoStr[2]) << 4) + int(EcuSerialNoStr[3])
                        EcuSerialNoIntList[2] = (int(EcuSerialNoStr[4]) << 4) + int(EcuSerialNoStr[5])
                        EcuSerialNoIntList[3] = (int(EcuSerialNoStr[6]) << 4) + int(EcuSerialNoStr[7])
                        EcuSerialNoIntList[4] = (int(EcuSerialNoStr[8]) << 4) + int(EcuSerialNoStr[9])
                        EcuSerialNoIntList[5] = (int(EcuSerialNoStr[10]) << 4) + int(EcuSerialNoStr[11])
                        EcuSerialNoIntList[6] = (int(EcuSerialNoStr[12]) << 4) + int(EcuSerialNoStr[13])
                        EcuSerialNoIntList[7] = (int(EcuSerialNoStr[14]) << 4) + int(EcuSerialNoStr[15])
                        EcuSerialNoIntList[8] = (int(EcuSerialNoStr[16]) << 4) + int(EcuSerialNoStr[17])
                        EcuSerialNoIntList[9] = (int(EcuSerialNoStr[18]) << 4) + int(EcuSerialNoStr[19])
                        print("EcuSerialNoIntList=", EcuSerialNoIntList)
                        #将列表转化为元组
                        EcuSerialNoBCD = tuple(EcuSerialNoIntList)
                        print("EcuSerialNoBCD=", EcuSerialNoBCD)
                        if not self.conn.is_open():
                            self.conn.open()  # 打开连接
                        try:
                            self.udsclient.change_session(1)
                            self.udsclient.change_session(3)
                            self.udsclient.change_session(96)
                            self.udsclient.unlock_security_access(97)
                            self.udsclient.write_data_by_identifier(did = 0xF18C, value = EcuSerialNoBCD)
                            # 输出信息
                            self.tb_message.append("写入序列号成功。")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            self.conn.close()
                        except:
                            print("写入序列号失败！")
                            self.tb_message.append("提示：写入序列号失败！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        print("输入的序列号不符合规范")
                        self.tb_message.append("提示：输入的序列号不符合规范,请输入20个数字！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("通道未连接！")
            self.tb_message.append("提示：通道未连接，请先打开通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    #写入零件号
    def WriteSparePartNum(self):
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("零件号")
                    ProgrammingDate = self.lineEdit_SparePartNum.text()
                    if (len(ProgrammingDate) < 21) and (len(ProgrammingDate) > 0):
                        if len(ProgrammingDate) < 20:
                            ProgrammingDate += (20 - len(ProgrammingDate)) * " "
                        print("ProgrammingDate",ProgrammingDate)
                        if not self.conn.is_open():
                            self.conn.open()  # 打开连接

                        try:
                            self.udsclient.change_session(1)
                            self.udsclient.change_session(3)
                            self.udsclient.change_session(96)
                            self.udsclient.unlock_security_access(97)
                            self.udsclient.write_data_by_identifier(did=0xF187, value=ProgrammingDate)
                            # 输出信息
                            self.tb_message.append("写入零件号成功。")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            self.conn.close()
                        except:
                            print("写入零件号失败！")
                            self.tb_message.append("写入零件号失败！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        print("输入的零件号不符合规范")
                        self.tb_message.append("提示：输入的零件号不符合规范，请输入20位ASCII数据！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("通道未连接！")
            self.tb_message.append("提示：通道未连接，请先连接通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 写入VIN
    def WriteVINCode(self):
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("VIN码")
                    VINData = self.lineEdit_VIN.text()

                    if (len(VINData) < 18) and (len(VINData) > 0):
                        if len(VINData) < 18:
                            VINData += (17 - len(VINData)) * " "
                        print("VINData:", VINData)
                        if not self.conn.is_open():
                            self.conn.open()  # 打开连接
                        try:
                            self.udsclient.change_session(1)
                            self.udsclient.change_session(3)
                            # self.udsclient.change_session(96)
                            self.udsclient.unlock_security_access(1)
                            print("1")
                            self.udsclient.write_data_by_identifier(did=0xF190, value=VINData)
                            # 输出信息
                            self.tb_message.append("VIN码写入成功。")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                            self.conn.close()
                        except:
                            print("写入VIN码失败！")
                            self.tb_message.append("写入VIN码失败！")
                            self.tb_message.ensureCursorVisible()
                            self.tb_message.moveCursor(self.tb_message.textCursor().End)
                    else:
                        print("输入的VIN码不符合规范")
                        self.tb_message.append("提示：输入的VIN码不符合规范，请输入小于17位的数据！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("通道未连接！")
            self.tb_message.append("提示：通道未连接，请先连接通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 写入网络配置信息
    def WriteNetConfigure(self):
        configIndex = self.comboBox_cnfigure.currentIndex()
        configText = self.comboBox_cnfigure.itemText(configIndex)
        if configText == "EV":
            configData = (0,0,0,0,0,0,0,0)
        elif configText == "FV":
            configData = (0,0,0,0,0,1,0,0)
        if self.isCh1Open:
            if self.isCh1HasMes:
                if self.m_CanRead == False:
                    print("写网络配置信息")
                    if not self.conn.is_open():
                        self.conn.open()  # 打开连接
                    try:
                        self.udsclient.change_session(1)
                        self.udsclient.change_session(3)
                        # self.udsclient.change_session(96)
                        self.udsclient.unlock_security_access(1)
                        self.udsclient.write_data_by_identifier(did=0xF101, value=configData)
                        # 输出信息
                        self.tb_message.append("车型码配置成功。")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                        self.conn.close()
                    except:
                        print("写入车型配置失败！")
                        self.tb_message.append("写入车型配置失败！")
                        self.tb_message.ensureCursorVisible()
                        self.tb_message.moveCursor(self.tb_message.textCursor().End)
                else:
                    self.tb_message.append("提示：请先停止挡位显示！")
                    self.tb_message.ensureCursorVisible()
                    self.tb_message.moveCursor(self.tb_message.textCursor().End)
            else:
                self.tb_message.append("提示：CAN网络上没有报文！")
                self.tb_message.ensureCursorVisible()
                self.tb_message.moveCursor(self.tb_message.textCursor().End)
        else:
            print("通道未连接！")
            self.tb_message.append("提示：通道未连接，请先连接通道！")
            self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)
    # ------------------------------------------------------------------------------------- #
    # 定时函数
    def myTimer3E(self):
        timer = QTimer(self)
        timer.timeout.connect(self.service3E)
        timer.start(3000)

    #  定时发送3E服务
    def service3E(self):
        i = 0
        if self.is_extendMode:
            while (i < 5):  # 5次发送不成功则退出
                uds3E = self.CanMessage("uds3E")
                ret = self.WriteFrame(uds3E)
                if ret == PCAN_ERROR_OK:
                    break
                else:
                    i += 1
                    continue
            if i >= 5:
                print("发送失败！")
                return
        else:
            print("不发送3E服务")

    # 显示Snap shot信息
    def showDtcSnapShot(self, data, configuration):
        snapShotDateRaw = list(data)
        self.tb_message.append("故障快照如下：")
        self.tb_message.ensureCursorVisible()
        if configuration == "FV":
            if (snapShotDateRaw[7] == 0xCF) and (snapShotDateRaw[8] == 0x0):
                system_voltage = (snapShotDateRaw[9]<<8)+snapShotDateRaw[10]
                self.tb_message.append("1、供电电压为："+str((system_voltage/100)+3)+"V")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[11] == 0xCF) and (snapShotDateRaw[12] == 0x1):
                vehicle_speed = (snapShotDateRaw[13]<<8)+snapShotDateRaw[14]
                self.tb_message.append("2、车辆速度为："+str(vehicle_speed*0.05625)+"Km/h")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[15] == 0xCF) and (snapShotDateRaw[16] == 0x2):
                engine_speed = (snapShotDateRaw[17]<<8)+snapShotDateRaw[18]
                self.tb_message.append("3、发动机转速为："+str(engine_speed*0.25)+"RPM")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[19] == 0xCF) and (snapShotDateRaw[20] == 0x3):
                total_mileage = (snapShotDateRaw[21]<<16) + (snapShotDateRaw[22]<<8)+snapShotDateRaw[23]
                self.tb_message.append("4、行驶总里程为："+str(total_mileage*0.1)+"Km")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[24] == 0x16) and (snapShotDateRaw[25] == 0x0):
                button_status = snapShotDateRaw[26]
                self.tb_message.append("5、按钮状态为："+str(hex(button_status)))
                self.tb_message.ensureCursorVisible()
                if (button_status & 0x1) == 0x1:
                    self.tb_message.append("               " + "P按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "P按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>1) & 0x1) == 0x1:
                    self.tb_message.append("               " + "R按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "R按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>2) & 0x1) == 0x1:
                    self.tb_message.append("               " + "N按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "N按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>3) & 0x1) == 0x1:
                    self.tb_message.append("               " + "H按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "H按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>4) & 0x1) == 0x1:
                    self.tb_message.append("               " + "L按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "L按键未激活")
                    self.tb_message.ensureCursorVisible()
        elif configuration == "EV":
            if (snapShotDateRaw[7] == 0xCF) and (snapShotDateRaw[8] == 0x0):
                system_voltage = (snapShotDateRaw[9] << 8) + snapShotDateRaw[10]
                self.tb_message.append("1、供电电压为：" + str((system_voltage / 100) + 3) + "V")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[11] == 0xCF) and (snapShotDateRaw[12] == 0x1):
                vehicle_speed = (snapShotDateRaw[13] << 8) + snapShotDateRaw[14]
                self.tb_message.append("2、车辆速度为：" + str(vehicle_speed * 0.05625) + "Km/h")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[15] == 0xCF) and (snapShotDateRaw[16] == 0x3):
                total_mileage = (snapShotDateRaw[17]<<16) + (snapShotDateRaw[18]<<8)+snapShotDateRaw[19]
                self.tb_message.append("3、行驶总里程为："+str(total_mileage*0.1)+"Km")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[20] == 0xCF) and (snapShotDateRaw[21] == 0x5):
                motor_speed = (snapShotDateRaw[22]<<8)+snapShotDateRaw[23]
                self.tb_message.append("4、电机转速为："+str((motor_speed)-20000)+"RPM")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[24] == 0xCF) and (snapShotDateRaw[25] == 0x6):
                total_voltage = (snapShotDateRaw[26]<<8)+snapShotDateRaw[27]
                self.tb_message.append("5、动力电池总电压为："+str((total_voltage)*0.1)+"V")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[28] == 0xCF) and (snapShotDateRaw[29] == 0x7):
                SOC = (snapShotDateRaw[30]<<8)+snapShotDateRaw[31]
                self.tb_message.append("6、动力电池剩余电量为："+str((SOC)*0.1)+"%")
                self.tb_message.ensureCursorVisible()
            if (snapShotDateRaw[32] == 0x16) and (snapShotDateRaw[33] == 0x0):
                button_status = snapShotDateRaw[34]
                self.tb_message.append("7、按钮状态为："+str(hex(button_status)))
                self.tb_message.ensureCursorVisible()
                if (button_status & 0x1) == 0x1:
                    self.tb_message.append("               " + "P按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "P按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>1) & 0x1) == 0x1:
                    self.tb_message.append("               " + "R按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "R按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>2) & 0x1) == 0x1:
                    self.tb_message.append("               " + "N按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "N按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>3) & 0x1) == 0x1:
                    self.tb_message.append("               " + "H按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "H按键未激活")
                    self.tb_message.ensureCursorVisible()
                if ((button_status>>4) & 0x1) == 0x1:
                    self.tb_message.append("               " + "L按键激活")
                    self.tb_message.ensureCursorVisible()
                else:
                    self.tb_message.append("               " + "L按键未激活")
                    self.tb_message.ensureCursorVisible()
        self.tb_message.moveCursor(self.tb_message.textCursor().End)


    # 在文本框打印DTC信息
    def show_DTC(self, list):
        for i in range(len(list)):
            if list[i].id == 0xC07388:
                self.tb_message.append("UC07388:CAN busoff FV. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xC07488:
                self.tb_message.append("UC07388:CAN busoff EV. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0x911716:
                self.tb_message.append("B111716:系统供电电压过低. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0x911717:
                self.tb_message.append("B111717:系统供电电压过高. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xE20D00:
                self.tb_message.append("U220D00:网络管理跛行回家故障. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0x16019E:
                self.tb_message.append("P16019E:P按钮卡滞. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0x16029E:
                self.tb_message.append("P16029E:R按钮卡滞. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0x16039E:
                self.tb_message.append("P16039E:N按钮卡滞.")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0x16049E:
                self.tb_message.append("P16049E:H按钮卡滞.")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0x16059E:
                self.tb_message.append("P16059E:L按钮卡滞.")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xC10087:
                self.tb_message.append("U010087:ECM节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD20682:
                self.tb_message.append("U120682:ECM节点Rolling counter错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD40683:
                self.tb_message.append("U140683:ECM节点Checksum错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD1C087:
                self.tb_message.append("U11C087:BCM节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD21582:
                self.tb_message.append("U121582:BCM节点Rolling counter错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD41583:
                self.tb_message.append("U141583:BCM节点Checksum错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD18287:
                self.tb_message.append("U118287:MMI节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD18187:
                self.tb_message.append("U118187:DASH节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD11087:
                self.tb_message.append("U111087:GBC节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD21482:
                self.tb_message.append("U121482:GBC节点Rolling counter错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD41483:
                self.tb_message.append("U141583:GBC节点Checksum错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD10087:
                self.tb_message.append("U110087:VCU节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD20F82:
                self.tb_message.append("U120F82:VCU节点Rolling counter错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD20F83:
                self.tb_message.append("U140F83:VCU节点Checksum错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD10587:
                self.tb_message.append("U110587:MCU节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD20582:
                self.tb_message.append("U120582:MCU节点Rolling counter错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD40F83:
                self.tb_message.append("U140583:MCU节点Checksum错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD10487:
                self.tb_message.append("U110487:BMS节点通讯丢失. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD20982:
                self.tb_message.append("U120982:BMS节点Rolling counter错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD40983:
                self.tb_message.append("U140983:BMS节点Checksum错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD20B82:
                self.tb_message.append("U120B82:ECM_DrvInfo节点Rolling counter错误. ")
                self.tb_message.ensureCursorVisible()
            elif list[i].id == 0xD40B83:
                self.tb_message.append("U140B83:ECM_DrvInfo节点Checksum错误. ")
                self.tb_message.ensureCursorVisible()
            self.tb_message.moveCursor(self.tb_message.textCursor().End)

    # 将列表按指定长度分割
    def list_of_groups(self, init_list, childern_list_len):
        list_of_groups = zip(*(iter(init_list),) * childern_list_len)
        end_list = [list(i) for i in list_of_groups]
        count = len(init_list) % childern_list_len
        end_list.append(init_list[-count:]) if count != 0 else end_list
        return end_list

    #报文接收函数
    def isotp_rcv(self):
        # We execute the "Read" function of the PCANBasic
        result = self.m_objPCANBasic.Read(self.m_PcanHandle)
        if result[0] == PCAN_ERROR_OK:
            # We show the received message
            RevMsg = TPCANMsg()
            RevMsg.ID = result[1].ID
            RevMsg.DLC = result[1].LEN
            for i in range(8 if (result[1].LEN > 8) else result[1].LEN):
                RevMsg.DATA[i] = result[1].DATA[i]
            RevMsg.MSGTYPE = result[1].MSGTYPE
        else:
            RevMsg = None
        return RevMsg

    #报文发送函数
    def isotp_send(self, isotp_msg):
        # isotp_msg.data.extend(bytearray([0xCC] * (8-len(isotp_msg.data))))
        CANMsg = TPCANMsg()
        CANMsg.ID = isotp_msg.arbitration_id
        CANMsg.LEN = isotp_msg.dlc
        CANMsg.MSGTYPE = PCAN_MESSAGE_STANDARD
        # If a remote frame will be sent, the data bytes are not important.
        if self.m_RemoteCHB.get():
            CANMsg.MSGTYPE |= PCAN_MESSAGE_RTR.value
        else:
            # We get so much data as the Len of the message
            for i in range(len(isotp_msg.data)):
                CANMsg.DATA[i] = isotp_msg.data[i]
        # The message is sent to the configured hardware
        ret = self.m_objPCANBasic.Write(self.m_PcanHandle, CANMsg)
        if ret != PCAN_ERROR_OK:
            print("发送失败")
        return

    #安全算法
    def hash_sha256(self, data):
        if isinstance(data, str):  # 如果输入的是字符串
            s = hashlib.sha256()  # Get the hash algorithm.
            s.update(data.encode('utf-8'))  # Hash the data.
            hashcode = s.hexdigest()  # Get he hash value.
        elif isinstance(data, bytes):  # 如果输入的是二进制数
            s = hashlib.sha256()  # Get the hash algorithm.
            s.update(data)  # Hash the data.
            hashcode = s.hexdigest()  # Get he hash value.
        else:
            print("Input data is not hashable.")
        return (hashcode)

    def SecAlgo(self, level, seed):
        print("SecAlgo")
        print("level=",level)
        bSeed = seed
        Cal = []
        Key = [0,0,0,0]
        if level == 0x01:
            print("level01")
            for i in range (4):
                Cal.append(bSeed[i] ^ ecuXorArray[i])
            Key[0] = (((Cal[2] & 0xF0) << 4) | (Cal[3] & 0xF0))&0xFF
            Key[1] = (((Cal[3] & 0x2F) << 2) | (Cal[1] & 0x03))&0xFF
            Key[2] = (((Cal[1] & 0xFC) >> 2) | (Cal[0] & 0xC0))&0xFF
            Key[3] = (((Cal[0] & 0x0F) << 4) | (Cal[2] & 0x0F))&0xFF
            remainder = (Key[0]<<24)+(Key[1]<<16)+(Key[2]<<8)+Key[3]
            output_key = (remainder).to_bytes(4, 'big', signed=False)

        elif level == 0x61:
            print("level61")
            for i in range (4):
                Cal.append(bSeed[i] ^ ecuXorArray60[i])
            Key[0] = (((Cal[1] & 0x7F) << 2) | (Cal[2] & 0xF0))&0xFF
            Key[1] = (((Cal[0] & 0xEC) >> 2) | (Cal[1] & 0x7E))&0xFF
            Key[2] = (((Cal[3] & 0xF0) >> 4) | (Cal[0] & 0x2C))&0xFF
            Key[3] = (((Cal[2] & 0x0F) << 4) | (Cal[3] & 0x7d))&0xFF
            remainder = (Key[0]<<24)+(Key[1]<<16)+(Key[2]<<8)+Key[3]
            output_key = (remainder).to_bytes(4, 'big', signed=False)
            print("output_key=",output_key)

        elif level == 0x09:
            print("level09")
            for i in range(4):
                Cal.append(bSeed[i] ^ ecuXorArray[i])
            Key[0] = (((Cal[1] & 0x7F) << 2) | (Cal[2] & 0xF0))&0xFF
            Key[1] = (((Cal[0] & 0xEC) >> 2) | (Cal[1] & 0x7E))&0xFF
            Key[2] = (((Cal[3] & 0xF0) >> 4) | (Cal[0] & 0x2C))&0xFF
            Key[3] = (((Cal[2] & 0x0F) << 4) | (Cal[3] & 0x7d))&0xFF
            remainder = (Key[0] << 24) + (Key[1] << 16) + (Key[2] << 8) + Key[3]
            output_key = (remainder).to_bytes(4, 'big', signed=False)
        return output_key
    # ------------------------------------------------------------------------------------- #

# ------------------------------------------------------------------------------------- #
if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    app = qw.QApplication(sys.argv)
    w = myMainWindow()
    w.show()
    sys.exit(app.exec_())
